package com.testitems.config.security;

import com.testitems.Util.TestItemsUtils;
import com.testitems.properties.JwtProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

/**
 * @author GFH
 * @since 2021-11-20
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private MyUserDetailService userDetailService;

    /**
     *
     * 流程
     * 先获取请求头中的jwttoken 判断token是否存
     *   存在
     *      A、存在时 从jwt令牌中 获取用户名 用户名存在说明jwt令牌是合法的 可以用秘钥解签
     *          判断 用户不为空 并且没有被Security 认证过
     *              根据用户名查询用户信息
     *                  判断 用户token是否过期
     *                      没有过期表示jwt令牌是合法的
     *                          给使用jwt令牌的用户进行授权 有此权限就不需要再次认证
     *             用户为空 或者 Security认证过
     *                  放行继续执行其他的过滤
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        final String jwtToken = request.getHeader(jwtProperties.getHeader());

        if (StringUtils.isNotBlank(jwtToken)) {
            final String username = jwtTokenUtil.getUserNameFromToken(jwtToken);
            if (StringUtils.isNotBlank(username) && SecurityContextHolder.getContext().getAuthentication() == null) {
                final UserInfo userInfo = (UserInfo) userDetailService.loadUserByUsername(username);
                if (jwtTokenUtil.validateToken(jwtToken, userInfo)) {
                    final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userInfo, null, userInfo.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        // 获取全部请求头
//        Enumeration<String> headerNames = request.getHeaderNames();
//        String headerName = "";
//        while (headerNames.hasMoreElements()) {
//            headerName = headerNames.nextElement();
//            System.out.println(headerName + ":" + request.getHeader(headerName));
//        }

        // 当前身份放于线程内
        TestItemsUtils.ThreadLocal.setJwtToken(request.getHeader("jwtToken"));

        filterChain.doFilter(request, response);
    }
}
